﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;


public static class TransformExtension
{
    #region 方向相关
    /// <summary>
    /// 旋转并朝向摄像机的Y旋转轴，用于3D游戏中的看向。
    /// </summary>
    public static void LookAtCameraY(this Transform transform)
    {
        Vector2 targetPos = new Vector2(Camera.main.transform.position.x, Camera.main.transform.position.z);
        Vector2 pos = new Vector2(transform.position.x, transform.position.z);
        Vector2 dir = (pos - targetPos).normalized;
        float angle = Mathf.Atan2(dir.y, -dir.x);
        transform.eulerAngles = new Vector3(transform.eulerAngles.x, angle * Mathf.Rad2Deg - 90, transform.eulerAngles.z);
    }
    public static void LookAtY(this Transform transform, Vector3 target)
    {
        Vector2 targetPos = new Vector2(target.x, target.z);
        Vector2 pos = new Vector2(transform.position.x, transform.position.z);
        Vector2 dir = (pos - targetPos).normalized;
        float angle = Mathf.Atan2(dir.y, -dir.x);
        transform.eulerAngles = new Vector3(transform.eulerAngles.x, angle * Mathf.Rad2Deg - 90, transform.eulerAngles.z);
    }

    public static void RotateAroundSourceCode(this Transform transform, Vector3 pivotPoint, Vector3 axis, float angle)
    {
        Quaternion rot = Quaternion.AngleAxis(angle, axis);
        transform.position = rot * (transform.position - pivotPoint) + pivotPoint;
        transform.rotation = rot * transform.rotation;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="position"></param>
    /// <param name="rotation"></param>
    /// <param name="pivotPoint=中心向量"></param>
    /// <param name="axis"></param>
    /// <param name="angle"></param>
    /// <returns></returns>
    public static Tuple<Vector3, Quaternion> RotateAround(this Vector3 position, Quaternion rotation, Vector3 pivotPoint, Vector3 axis, float angle)
    {
        Quaternion rot = Quaternion.AngleAxis(angle, axis);//创建一个围绕 axis 旋转 angle 度的旋转，这里可以是很小的角度
        //position = rot * position;//将旋转后角度等比应用到坐标。
        position = rot * (position - pivotPoint) + pivotPoint;//这一步是因为四元数要基于原点，所以position - pivotPoint=将旋转偏移基于0,0。偏移过后再重新加回pivotPoint原点的偏移坐标。
        rotation = rot * rotation;
        return new Tuple<Vector3, Quaternion>(position, rotation);
    }

#endregion


    public static Transform[] GetChildren(this Transform transform)
    {
        Transform[] transforms = new Transform[transform.childCount];
        for (int i = 0; i < transform.childCount; i++)
        {
            transforms[i] = transform.GetChild(i);
        }
        return transforms;
    }
    public static GameObject[] GetChildrenGameObject(this Transform transform)
    {
        GameObject[] transforms = new GameObject[transform.childCount];
        for (int i = 0; i < transform.childCount; i++)
        {
            transforms[i] = transform.GetChild(i).gameObject;
        }
        return transforms;
    }

    public static void GetChildrenAction(this Transform transform, Action<Transform> child)
    {
        for (int i = 0; i < transform.childCount; i++)
        {
            child.Invoke(transform.GetChild(i));
        }
    }

    /// <summary>
    /// 删除所有子物体
    /// </summary>
    /// <param name="transform"></param>
    public static void DestroyAllChildren(this Transform transform)
    {
        foreach (Transform child in transform) GameObject.Destroy(child.gameObject);
    }

    public static void DestroyAllChildrenImmediate(this Transform transform)
    {
        foreach (Transform child in transform) GameObject.DestroyImmediate(child.gameObject);
    }
    /// <summary>
    /// 获得距离坐标最近的子物体
    /// </summary>
    /// <param name="transform"></param>
    /// <param name="postion"></param>
    /// <returns></returns>
    public static Transform NearestChildren(this Transform transform, Vector3 postion)
    {
        int index = 0;
        float minMagnitude = (transform.GetChild(0).position - postion).sqrMagnitude;
        for (int i = 1; i < transform.childCount; i++)
        {
            Transform child = transform.GetChild(i);
            float magnitude = (child.position - postion).sqrMagnitude;
            if (magnitude < minMagnitude)
            {
                minMagnitude = magnitude;
                index = i;
            }
        }
        return transform.GetChild(index);
    }

    public static Transform NearestChildren(this Transform transform, Vector3 postion, out int index)
    {
        index = 0;
        float minMagnitude = (transform.GetChild(0).position - postion).sqrMagnitude;
        for (int i = 1; i < transform.childCount; i++)
        {
            Transform child = transform.GetChild(i);
            float magnitude = (child.position - postion).sqrMagnitude;
            if (magnitude < minMagnitude)
            {
                minMagnitude = magnitude;
                index = i;
            }
        }
        return transform.GetChild(index);
    }

    public static int NearestChildrenIndex(this Transform transform, Vector3 postion)
    {
        int index = 0;
        float minMagnitude = (transform.GetChild(0).position - postion).sqrMagnitude;
        for (int i = 1; i < transform.childCount; i++)
        {
            Transform child = transform.GetChild(i);
            float magnitude = (child.position - postion).sqrMagnitude;
            if (magnitude < minMagnitude)
            {
                minMagnitude = magnitude;
                index = i;
            }
        }
        return index;
    }



}
 public static partial class RectTransformExtension
{

    public static void TopLeft(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = Vector2.up;
        rectTransform.anchorMax = Vector2.up;
        rectTransform.pivot = Vector2.up;
    }
    public static void Top(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = new Vector2(0.5f, 1);
        rectTransform.anchorMax = new Vector2(0.5f, 1);
        rectTransform.pivot = new Vector2(0.5f, 1);
    }
    public static void TopRight(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = Vector2.one;
        rectTransform.anchorMax = Vector2.one;
        rectTransform.pivot = Vector2.one;
    }
    public static void Left(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = new Vector2(0, 0.5f);
        rectTransform.anchorMax = new Vector2(0, 0.5f);
        rectTransform.pivot = new Vector2(0, 0.5f);
    }

    public static void Middle(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
        rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
        rectTransform.pivot = new Vector2(0.5f, 0.5f);
    }
    public static void Right(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = new Vector2(1, 0.5f);
        rectTransform.anchorMax = new Vector2(1, 0.5f);
        rectTransform.pivot = new Vector2(1, 0.5f);

    }
    public static void BottomLeft(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = Vector2.zero;
        rectTransform.anchorMax = Vector2.zero;
        rectTransform.pivot = Vector2.zero;
    }
    public static void Bottom(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = new Vector2(0.5f, 0);
        rectTransform.anchorMax = new Vector2(0.5f, 0);
        rectTransform.pivot = new Vector2(0.5f, 0);
    }

    public static void BottomRight(this RectTransform rectTransform)
    {
        rectTransform.anchorMin = Vector2.right;
        rectTransform.anchorMax = Vector2.right;
        rectTransform.pivot = Vector2.right;
    }
}


